/*
 *  $Id: TargetRequest.cs 1220 2010-11-30 16:25:44Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

namespace Ragima {
    /// <summary>
    /// Абстрактный класс запроса цели, передается при инициализации цели.
    /// </summary>
    public abstract class TargetRequest {
        /// <summary>
        /// Игрок, для которого запрашивается цель.
        /// </summary>
        public abstract Player Player { get; }
        /// <summary>
        /// Тот, чье действие требует цели.
        /// </summary>
        public abstract AbstractObject Caster { get; }
        /// <summary>
        /// Регион карты, требующей цели. Используется для отрисовки чего-либо поверх карты.
        /// </summary>
        public abstract Region Region { get; }
        /// <summary>
        /// Получение объекта цели.
        /// </summary>
        /// <returns>Цель.</returns>
        public abstract TargetType GetTarget();
        /// <summary>
        /// Выполнение действия при успешном выборе цели.
        /// </summary>
        /// <param name="args">Данные о выбранной цели<./param>
        public abstract void Execute(TargetArgs args);
    }

    /// <summary>
    /// Запрос цели при использовании карты в руках игрока.
    /// </summary>
    public class HandCardTargetRequest : TargetRequest {
        private PlayerHandCardRegion _region;

        public HandCardTargetRequest(PlayerHandCardRegion region) {
            _region = region;
        }

        public override Player Player {
            get { return _region.Player; }
        }

        public override AbstractObject Caster {
            get { return _region.Player; }
        }

        public override Region Region {
            get { return _region; }
        }

        public override TargetType GetTarget() {
            return _region.Card.Card.Target;
        }

        public override void Execute(TargetArgs args) {
            if (!args.Player.TestMana(_region.Card.Card.GetManaCostFor(args), true))
                return;
            if (!_region.Card.Card.IsPossibleAction(args))
                return;
            Player.Game.Mode.AddEvent(new Events.UseCard(_region.Card, args));
            _region.Selected = false;
            Player.ResetSelection();
        }
    }

    /// <summary>
    /// Запрос цели при использовании чьей-либо способности.
    /// </summary>
    public class AbilityTargetRequest : TargetRequest {
        private AbilityRegion _region;

        public AbilityTargetRequest(AbilityRegion region) {
            _region = region;
        }

        public override Player Player {
            get { return Caster.Owner; }
        }

        public override AbstractObject Caster {
            get { return _region.Owner; }
        }

        public override Region Region {
            get { return _region; }
        }

        public override TargetType GetTarget() {
            return _region.Ability.Target;
        }

        public override void Execute(TargetArgs args) {
            if (!args.Player.TestMana(_region.Ability.GetManaCostFor(args), true))
                return;
            if (!_region.Ability.IsPossibleAction(args))
                return;
            Player.Game.Mode.AddEvent(new Events.UseAbility(_region.Ability, args));
            _region.Selected = false;
            Player.ResetSelection();
        }
    }

    /// <summary>
    /// Запрос цели при выборе существа.
    /// </summary>
    public class CreatureTargetRequest : TargetRequest {
        private Creature _creature;

        public CreatureTargetRequest(Creature creature) {
            _creature = creature;
        }

        public override Player Player {
            get { return _creature.Owner; }
        }

        public override AbstractObject Caster {
            get { return _creature; }
        }

        public override Region Region {
            get { return null; }
        }

        public override TargetType GetTarget() {
            if (Player.State == PlayerState.Offence)
                return new OffenceTarget(_creature);
            else
                return new DefenceTarget(_creature);
        }

        public override void Execute(TargetArgs args) {
            Player.Game.Mode.AddEvent(new Events.CreatureAction(args));
            Player.ResetSelection();
        }
    }
}
